import socket

# 异或加密/解密函数
def xor_crypt(data, key):
    return bytes([b ^ key for b in data])


def show_menu():
    print("\n===== 网络通信系统菜单 =====")
    print("1. 基本通信功能")
    print("2. 加密文件传输功能")
    print("0. 退出")
    return input("请选择功能 (0-2): ")


def basic_communication(client):
    while True:
        message = input("请输入要发送的消息: ")
        if message == "exit":
            client.send(message.encode())
            print("通信中断")
            break
        client.send(message.encode())
        response = client.recv(1024).decode()
        print(f"服务器响应: {response}")


def encrypted_transfer(client):
    try:
        # 获取异或加密密钥
        key = int(input("请输入异或加密密钥(0-255): "))
        if not 0 <= key <= 255:
            raise ValueError

        #传输密钥和文件名
        client.send(str(key).encode())
        filename = input("请输入要加密传输的文件: ")
        client.send(filename.encode())

        # 读取并加密文件
        with open(filename, "rb") as file:
            file_data = file.read()
        encrypted_data = xor_crypt(file_data, key)

        # 分块发送加密数据
        chunk_size = 4096
        for i in range(0, len(encrypted_data), chunk_size):
            client.send(encrypted_data[i:i + chunk_size])

        # 发送结束标记
        client.shutdown(socket.SHUT_WR)

        # 接收服务器响应
        response = client.recv(1024).decode()
        print(f"服务器响应: {response}")

    except ValueError:
        print("错误: 密钥必须是0-255之间的整数")
    except Exception as e:
        print(f"文件传输失败: {str(e)}")


def main():
    # 建立连接
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        client.connect((HOST, PORT))

        while True:
            choice = show_menu()

            if choice == "0":
                print("退出系统")
                break

            client.send(choice.encode())

            if choice == "1":
                basic_communication(client)
            elif choice == "2":
                encrypted_transfer(client)
            else:
                print("无效选择，请重新输入")

    except ConnectionRefusedError:
        print("错误: 无法连接到服务器")
    except Exception as e:
        print(f"发生错误: {str(e)}")
    finally:
        client.close()  # 关闭连接


HOST = "120.46.29.197"
PORT = 8080
main()